home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1996 #15
/
Monster Media Number 15 (Monster Media)(July 1996).ISO
/
prog_c
/
cuj0896.zip
/
KREHBIEL.ZIP
/
VBE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-15
|
4KB
|
145 lines
Listing 1:
/*--------------------------------------------------------------
vbe.c VESA Super VGA Interface
----------------------------------------------------------------
Platform: IBMPC/MSDOS.
Functions:
VbeGetVbeInfo Return VBE information
VbeGetModeInfo Return VESA mode information
VbeSetMode Initialize video mode
VbeSetPalette Load DAC palette
VbeSetWindow Move memory window
VbeWrite Copy buffer to display
Edit history:
04/12/96 C.Krehbiel. Implemented VBE 2.0 interface in
MSVC 1.0, medium memory model.
--------------------------------------------------------------*/
#include <string.h>
#include <dos.h>
#include "vbe.h" /* exports and data types */
/*--------------------------------------------------------------
local data
--------------------------------------------------------------*/
static VbeInfo_t _VbeInfo; /* current vbe info */
static ModeInfo_t _ModeInfo; /* current mode info */
static int _Width; /* scan line width in bytes */
static long _Window; /* memory window size in bytes */
static int _Segment; /* memory window segment */
/*--------------------------------------------------------------
exported functions
--------------------------------------------------------------*/
int VbeGetVbeInfo(VbeInfo_t far *p)
/* fetches the vbe info block; returns 0 if no vbe. */
{
union REGS r={0x4f00,0,0,0,0,FP_OFF(p)};
struct SREGS s={FP_SEG(p)};
if(!p) return 0;
_fmemset(p,0,sizeof(VbeInfo_t));
_fmemcpy(p->VbeSignature,"VBE2",4);
int86x(0x10,&r,&r,&s);
if(_fmemcmp(p->VbeSignature,"VESA",4)) return 0;
return r.x.ax==0x4f;
}
int VbeGetModeInfo(int mode,ModeInfo_t far *p)
/* fetches the mode info block for the specified mode
number; returns 0 if mode unsupported by vbe. */
{
union REGS r={0x4f01,0,mode,0,0,FP_OFF(p)};
struct SREGS s={FP_SEG(p)};
if(!p) return 0;
_fmemset(p,0,sizeof(ModeInfo_t));
int86x(0x10,&r,&r,&s);
return r.x.ax==0x4f;
}
int VbeSetMode(int mode)
/* initializes the requested video mode; returns 0 if
there's no vbe or the mode is unavailable. */
{
union REGS r={0x4f02,mode};
if(!VbeGetVbeInfo(&_VbeInfo)) return 0;
if(mode>=0x100) /* svga mode */
{
if(!VbeGetModeInfo(mode,&_ModeInfo) ||
!(_ModeInfo.ModeAttributes&1)) return 0;
_Width=_ModeInfo.BytesPerScanLine;
_Window=1024L*_ModeInfo.WinSize; /* convert to bytes */
_Segment=_ModeInfo.WinASegment;
}
int86(0x10,&r,&r);
return r.x.ax==0x4f;
}
void VbeSetPalette(const char far *p,int start,int n)
/* loads the dac palette registers; uses bios on vbe
versions before 2.0 */
{
if(_VbeInfo.VbeVersion<0x200) /* use bios */
{
union REGS r={0x1012,start,n,FP_OFF(p)};
struct SREGS s={FP_SEG(p)};
int86x(0x10,&r,&r,&s);
}
else /* use vbe */
{
union REGS r={0x4f09,0,n,start,0,FP_OFF(p)};
struct SREGS s={FP_SEG(p)};
int86x(0x10,&r,&r,&s);
}
}
void VbeSetWindow(int window,int position)
/* repositions the indicates memory window to the new
position (in WinGranularity units). */
{
union REGS r={0x4f05,window,0,position};
int86(0x10,&r,&r);
}
void VbeWrite(int x,int y,int bytes,const char far *buffer)
/* copies the contents of the buffer (<64k) to display,
starting at pixel (x,y). */
{
long absolute=x+(long)y*_Width; /* absolute offset */
long position=absolute/_Window; /* of window */
long offset=absolute%_Window; /* of window */
char far *vram=MK_FP(_Segment,0); /* to window */
VbeSetWindow(0,(int)position);
if(offset+bytes>_Window) /* data overruns window */
{
int n=(int)(_Window-offset); /* bytes left */
_fmemcpy(vram+offset,buffer,n); /* display 1st part */
VbeSetWindow(0,(int)++position);/* move window */
_fmemcpy(vram,buffer+n,bytes-n);/* display rest */
}
else _fmemcpy(vram+offset,buffer,bytes);/* no overrun */
}
/*--------------------------------------------------------------
eof
--------------------------------------------------------------*/